#include "Displayer.h"
#include "Display.h"

#include "GameManager.h"

//Sets up camera properties
void Displayer::InitFrame()
{
	if (mCam == NULL) {
		printf("Displayer::InitFrame: Can't init frame without a Camera (NULL)\n");
	}

	glClearColor(mClearColor.x, mClearColor.y, mClearColor.z, mClearColor.a);
	glClear(GL_COLOR_BUFFER_BIT); 

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMultMatrixf(mCam->GetFloat(PROJECTION_MATRIX));

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glMultMatrixf(mCam->GetFloat(MODELVIEW_MATRIX));
}


void Displayer::AddDisplayPrimitive( DisplayPrimitive * inPrim) {
	if (GetDisplayItem(inPrim) == -1) {
		mDisplayList.push_back(inPrim);
	}
}

void Displayer::RemoveDisplayPrimitive( DisplayPrimitive * inPrim ) {
	int i = GetDisplayItem(inPrim);
	if (i != -1) {
		mDisplayList.erase(mDisplayList.begin() + i);
	}
}

int  Displayer::GetDisplayItem ( DisplayPrimitive * inPrim ) {
	for (int i = 0; i < this->mDisplayList.size(); ++i) {
		if (mDisplayList[i] == inPrim) {
			return i;
		}
	}

	return -1;
}

/*
void Displayer::DrawGrid( float cellSize,
						 const glm::vec2 & minPtFt, const glm::vec2 & maxPtFt) {
	
	glm::vec2 drawMinPt, drawMaxPt;
	
	drawMinPt = glm::vec2( ((int)(minPtFt.x/cellSize))*cellSize,
						  ((int)(minPtFt.y/cellSize))*cellSize);
	
	drawMaxPt = glm::vec2( ((int)(maxPtFt.x/cellSize))*cellSize,
						  ((int)(maxPtFt.y/cellSize))*cellSize);
		
	glm::vec2 wh = drawMaxPt - drawMinPt;
	
	glm::ivec2 dimWH = glm::ivec2((int)(wh.x/cellSize), (int)(wh.y/cellSize));

	
	glBegin(GL_LINES);
	for (float x = drawMinPt.x; x < drawMaxPt.x; x+= cellSize) {
		for (float y=drawMinPt.y; y < drawMaxPt.y; y+= cellSize) {
			glVertex2f(x, y);
			glVertex2f(x+cellSize, y);
			
			glVertex2f(x, y);
			glVertex2f(x, y+cellSize);
		}
	}
	glEnd();
	
}
*/

DisplayPrimitive * Displayer::AddFromDef( const DisplayPrimitiveDef * inDef )
{
	DisplayPrimitive * retVal = CreateDisplayPrimitive( inDef );
	AddDisplayPrimitive(retVal);

	return retVal;
}

//Goes through display lists and draws all the sprites.
void Displayer::Display() {
	
	//Can't do anything without a camera.
	if (this->mCam == NULL) {
		return;
	}
	
	//Sets up modelview and projection matrices in the camera.
	InitFrame();
	
	DrawDisplayList();
	
}

void Displayer::SetClearColor(float r, float g, float b, float a) {
	mClearColor = glm::vec4(r, g, b, a);
}


void Displayer::DrawDisplayList ()
{
	glColor4f(1.0,1.0,1.0,1.0);
	for (int i = 0; i < this->mDisplayList.size(); ++i) {
			mDisplayList[i]->Display();
	}
}

Camera * Displayer::GetCamera() {
	return this->mCam;
}

void Displayer::SetCamera( Camera * inCam )
{
	if (inCam == NULL)
		return;
	
	this->mCam = inCam;
}

void Displayer::Update( float ts )
{
	//XXX
	//Use reverse iterator

/*	std::stack< int > deleteStack;
	for (int i = mDisplayList.size()-1; i >= 0; --i)
	{
		mDisplayList[i]->Update(ts);
		if (mDisplayList[i]->Finished())
			deleteStack.push(i);
	}

	while (!deleteStack.empty() ) {
		int ndx = deleteStack.top();
		printf("Deleteing : %d\n", ndx);
		deleteStack.pop();

		mDisplayList.erase(mDisplayList.begin() + ndx);
	}
	*/
}


	